import 'package:black_movice/config/configs.dart';
import 'package:black_movice/models/BackModel.dart';
import 'package:black_movice/net/custom_http.dart';
import 'package:black_movice/routers.dart';
import 'package:black_movice/utils/Utils.dart';
import 'package:black_movice/utils/local_storage.dart';
import 'package:black_movice/views/components/common/cu_toast.dart';
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:get/get.dart' as get_package;
import 'package:http_mock_adapter/http_mock_adapter.dart';

class HttpClient implements CustomHttp {
  final Dio _dio = Dio();
  static HttpClient? _instance; //单例
  DioAdapter? _dioAdapter; //模拟适配器
  // 私有化构造函数
  HttpClient._();
  // 获取单例
  static HttpClient get getInstance {
    _instance ??= HttpClient._();
    return _instance!;
  }

  // 设置是否使用模拟数据
  void setUseMock(bool useMock) {
    if (useMock) {
      _dioAdapter = DioAdapter(dio: _dio);
      _dio.httpClientAdapter = _dioAdapter!;
    } else {
      _dio.httpClientAdapter = IOHttpClientAdapter();
    }
  }

  //设置模拟响应
  void setupMockResponse(String apiPath, Map<String, dynamic> mockData,
      {String requestType = 'post', int delaySeconds = 1}) {
    if (_dioAdapter == null) {
      throw Exception("模拟适配器未初始化，请先调用setUseMock(true)");
    }
    String url = Configs.instance.getBaseUrl + apiPath;
    switch (requestType.toLowerCase()) {
      case 'post':
        _dioAdapter!.onPost(
          url,
          (server) => server.reply(200, mockData,
              delay: Duration(seconds: delaySeconds)),
        );
        break;
      case 'get':
        _dioAdapter!.onGet(
          url,
          (server) => server.reply(200, mockData,
              delay: Duration(seconds: delaySeconds)),
        );
        break;
      // 可以根据需要添加更多请求类型的处理，如 put、delete 等
      default:
        throw Exception("不支持的请求类型: $requestType");
    }
  }

  @override
  Future<BackModel> request(String apiPath, Map<String, dynamic> data,
      {String requestType = 'Post'}) async {
    try {
      Map<String, dynamic> httpHeaders = {'token': Configs.token};
      // 设置请求头
      Options options = Options(headers: httpHeaders);
      Response? response;
      String url = Configs.instance.getBaseUrl + apiPath;
      Utils.logDebug("data的数据是$data,url是：$url");
      switch (requestType) {
        case "post":
          response =
              await _dio.post(url, queryParameters: data, options: options);
          break;
        case "get":
          response =
              await _dio.get(url, queryParameters: data, options: options);
          break;
        default:
          throw Exception("不支持的请求类型: $requestType");
      }
      return await _parseData(response);
    } on DioException catch (e) {
      // 处理 Dio 相关异常
      BackModel backModel = BackModel();
      backModel.code = 500;
      backModel.msg = "网络发生错误，稍后再试: $e";
      throw Exception(backModel.msg);
    } catch (e) {
      // 处理其他异常
      BackModel backModel = BackModel();
      backModel.code = 500;
      backModel.msg = "网络发生错误，稍后再试: $e";
      throw Exception(backModel.msg);
    }
  }

  // 格式化返回数据
  Future<BackModel> _parseData(Response response) async {
    try {
      Map<String, dynamic> scores = Map.from(response.data);
      BackModel backModel = BackModel.fromJson(scores);
      if (backModel.code != 200) {
        BackModel errorModel = BackModel();
        errorModel.code = backModel.code;
        errorModel.msg = backModel.msg;
        errorModel.data = backModel.data;
        CuToast.toast(backModel.msg); //统一错误消息提示框
        if (backModel.code == -1000) {
          //   token 过期
          await LocalStorage.removeToken();
          await LocalStorage.removeUserInfo();
          Configs.token = "";
          get_package.Get.offAllNamed(Routers.home);
        }
        return errorModel;
      }
      return backModel;
    } catch (e) {
      BackModel backModel = BackModel();
      backModel.code = 500;
      backModel.msg = "格式化返回数据有误: $e";
      throw Exception(e);
    }
  }
}
